/*
 * Copyright (c) 2007-2008 CACE Technologies, Davis (California)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/*
 * $cacever: turbocap2/api/TcApi.h,v 1.12 2008/05/08 00:49:05 gianlucav Exp $ 
 */

#ifndef __TC_API_HEADER__
#define __TC_API_HEADER__

#ifdef _WIN32
#include <windows.h>
#define TC_CALLCONV	__cdecl
#else  //_WIN32
#include <assert.h>
#define _ASSERT(a) assert(a)
#define C_ASSERT(expr) extern char __C_ASSERT__[(expr)?1:-1]
#define TRUE 1
#define FALSE 0
typedef void VOID, *PVOID;
typedef PVOID HANDLE;
typedef char CHAR, *PCHAR;
typedef unsigned char UCHAR, *PUCHAR;
typedef unsigned char BYTE, *PBYTE;
typedef unsigned short USHORT, *PUSHORT;
typedef unsigned long ULONG, *PULONG;
typedef unsigned long DWORD, *PDWORD;
typedef unsigned long long ULONGLONG, *PULONGLONG;
typedef long long LONGLONG, *PLONGLONG;
typedef int BOOLEAN, *PBOOLEAN;
typedef int BOOL, *PBOOL;
#define TC_CALLCONV	//__cdecl
#endif //_WIN32


#ifndef __in__
#define __in__
#endif //__in__
#ifndef __out__
#define __out__
#endif //__out__

/** @defgroup types_enums Types and enumerations
 *  @{
 */
//
// Flags for the Flags field in the TC_PACKET_HEADER
//
#define TC_PH_FLAGS_CHECKSUM	0x00000001	///< The packet contain the FCS at the end of the packet. 

/*!
	\brief The packet will be transmitted without any scheduling policy i.e. as soon as possible, respecting
	the minimum interframe gap (IFG) of the link layer.
	The \ref TC_PACKET_HEADER::Timestamp field is ignored by the transmission scheduler.
*/
#define TC_TX_SCHEDULING_MODE_NO_SCHED	0x00

/*!
	\brief Reserved.
*/
#define TC_TX_SCHEDULING_MODE_HW_REF	0x01
/*!
	\brief Reserved.
*/
#define TC_TX_SCHEDULING_MODE_SW_REF	0x02

/*!
	\brief Macro used to define the transmission scheduling policy for a packet.

	The result of this macro should be OR combined with the \ref TC_PACKET_HEADER::Flags field.
	\param a One of these values
	- \ref TC_TX_SCHEDULING_MODE_NO_SCHED
	- \ref TC_TX_SCHEDULING_MODE_HW_REF (currently not supported)
	- \ref TC_TX_SCHEDULING_MODE_SW_REF (currently not supported)
*/
#define TC_PH_FLAGS_TX_SCHEDULING_MODE(a)	((a)<<24)

/*!
	\brief Macro used to get the port ID a packet was received from.

	The macro should be applied to the \ref TC_PACKET_HEADER::Flags field.
	The result is an 8bit index in the array of physical ports returned by \ref TcPortQueryAggregatedPortList.
	In case the packet was captured on a physical port, the port Id is always 0.
*/
#define TC_PH_FLAGS_RX_PORT_ID(flags)	((UCHAR)((flags)>>24))

/*!
	\brief On reception, the received packet has an invalid frame check sequence (FCS)
*/
#define TC_PH_ERROR_CHECKSUM			0x00000001

/*!
	\brief On reception, the received packet had a sequence error. A valid delimiter sequence
	consists of 
	idle->start-of-frame(SOF)->data, ->pad(optional)->end-of-frame(EOF)-fill(optional)->idle
*/
#define TC_PH_ERROR_SEQUENCE	0x00000002
/*!
	\brief On reception, the received packet had a symbol error.
*/
#define TC_PH_ERROR_SYMBOL		0x00000004

/*!
	\brief On reception, the received packet had a data error.
*/
#define TC_PH_ERROR_DATA		0x00000008

/*!
	\brief Macro to align a 16 bit quantity on a 64bit boundary. Used when processing the packets
	contained in a packets buffer when \ref TcPacketsBufferGetBuffer is used.
*/
#define TC_ALIGN_USHORT_TO_64BIT(a) ((USHORT)(((USHORT)(a) + 7) & ((USHORT)0xFFF8)))


/*!
	\brief Header prepended to each packet during reception and transmission.
	
	On reception, this header is prepended to each packet, and it's generated
	by either the hardware or the underlying capture driver. 
	On transmission, this header should be generated by the transmission application
	and then passed to this library together with the packet payload. 
*/
typedef struct _TC_PACKET_HEADER
{
	/*!
		On reception, the timestamp of the packet, with nanosecond precision. The
			timestamp is taken when the first byte of the MAC header is received.
			The timestamp is the number of nanoseconds elapsed since midnight 
			Coordinated Universal Time (UTC) of January 1, 1970, not counting leap seconds.

		On transmission, the scheduled time for the transmission of the packet, with nanosecond
			precision. The Flags field defines the scheduling policy of the packet and how the
			timestamp will be interpreted by the underlying transmission engine or hardware.
		
		The timestamp is the number of nanoseconds elapsed since midnight 
		Coordinated Universal Time (UTC) of January 1, 1970, not counting leap seconds.
	*/
	ULONGLONG		Timestamp;
	/*!
		On reception, an OR combination of the following flags:
		- \ref TC_PH_FLAGS_CHECKSUM
		- the port ID the packet was received from, in case of a packet coming from an aggregating port.
			The port ID can be retrieved with the macro \ref TC_PH_FLAGS_RX_PORT_ID(\ref Flags).
	
		On transmission, an OR combination of the following flags should be used:
		- \ref TC_PH_FLAGS_CHECKSUM. It this flag is not set, the board will 
			append the valid FCS at the end of the packet.
		- the result of the TC_PH_FLAGS_TX_SCHEDULING_MODE(a) macro. If the result
			of this macro is not OR-combined to this field, the default scheduling mode
			is \ref TC_TX_SCHEDULING_MODE_NO_SCHED.
	*/
	ULONG			Flags;
	/*!
		On reception, the original length of the packet, computed from the beginning of the MAC header 
		(i.e. MAC destination address) to the end of the L2 payload. This field includes the FCS if the 
		\ref TC_PH_FLAGS_CHECKSUM bit is set in the \ref Flags field. If snapshot is 
		enabled (please see \ref TC_INST_FT_SNAPLEN), the captured part of the packet available after this
		header can be less than Length bytes. Please use \ref CapturedLength to obtain the actual number of
		captured bytes.
		
		On transmission, the length of the packet to be transmitted, computed from the beginning of the MAC header 
		(i.e. MAC destination address) to the end of the L2 payload. This field includes the FCS if the 
		\ref TC_PH_FLAGS_CHECKSUM bit is set in the \ref Flags field.
	*/
	USHORT			Length;
	/*!
		On reception, the captured length of the packet, i.e. the number of packets bytes actually available after this header.
		This value can be less than the original length of the packet (stored in the \ref Length field) if snapshot is 
		enabled (please see \ref TC_INST_FT_SNAPLEN). The value of this field is always less or equal to \ref Length.
		
		On transmission, this field should be set to the same value as \ref Length.
	*/
	USHORT			CapturedLength;
	/*!
		On reception, it contains a combination of hardware errors during the reception of the packet.
		The packet had a reception error if this field is different from 0.
		In case of errors, it's an OR combination of the following bit values
		- \ref TC_PH_ERROR_CHECKSUM
		- \ref TC_PH_ERROR_SYMBOL
		- \ref TC_PH_ERROR_SEQUENCE
		- \ref TC_PH_ERROR_DATA

		On transmission, it should be set to 0.
	*/
	ULONG			Errors;
	/*!
		On reception, the value of this field should be ignored. 

		On transmission, it should be set to 0.
	*/
	ULONG			Reserved0;
}
	TC_PACKET_HEADER;
typedef TC_PACKET_HEADER *PTC_PACKET_HEADER;

#ifndef DO_NOT_DEFINE_TC_HANDLES

/*!
	\brief Handle to a physical TurboCap board on the system. 

	\note
	- It's not possible to open or close a board handle. Board
		handles are returned by the following methods:
		- \ref TcPortQueryBoard
	- In order to check if two board handles correspond to the same
	  physical board on the system, you must use the function
	  \ref TcBoardIsEqual
*/
typedef HANDLE TC_BOARD;
typedef TC_BOARD *PTC_BOARD;

/*!
	\brief Handle to a TurboCap port.

	A port can be a physical port on a board, or an aggregating port.
	There are two kinds of aggregating ports:
	- TurboCap Aggregating Port (TcAP). This port aggregates the traffic
	  coming from all the TurboCap physical ports on the system. There is
	  only one TcAP port per system.
	- Board Aggregating Port (BAP). This port aggregates the traffic coming
	  from all the physical ports of a board. There is one single BAP port
	  per board on the system.

	\note
	- It's not possible to open or close a board handle. Board
		handles are returned by the following methods:
		- \ref TcQueryPortList
		- \ref TcPortQueryAggregatedPortList
		- \ref TcBoardQueryPortList
		- \ref TcInstanceGetPort
	- In order to check if two port handles correspond to the same
	  port (physical or aggregating) on the system, you must use the function
		- \ref TcPortIsEqual
*/
typedef HANDLE TC_PORT;
typedef TC_PORT *PTC_PORT;

/*!
	\brief Handle to a capture/injection port instance.

	When you need to send or receive traffic on a port, you need to have
	a \ref TC_INSTANCE, i.e. an open instance to a port. 
	Multiple instances can be opened against the same port, each one
	with its own reception/transmission parameters.
*/
typedef HANDLE TC_INSTANCE;
typedef TC_INSTANCE *PTC_INSTANCE;

/*!
	\brief Handle to a buffer containing packets to be received or transmitted.

	Packets are received in the form of buffer containing one or more packets.
	In the same fashion, packets that have to be transmitted should be assembled
	in a packets buffer and passed to the transmission functions of the library.
	Access to this buffer can be performed in two different ways:
	- (reception) through the provided APIs to scan the packets in the buffer or
	- (transmission) through the provided APIs to append a new packet to the buffer
	or
	- by retrieving the raw buffer pointer (throught the provided APIs) and manually
		reading/writing the packets in the buffer.

	In the former case, the packets are accessed through \ref TcPacketsBufferQueryNextPacket (reception)
	and \ref TcPacketsBufferCommitNextPacket (transmission). 
	In the latter case, the raw buffer is retrieved with \ref TcPacketsBufferGetBuffer, its effective length
	(i.e. the number of bytes effectively used in the buffer) is obtained with \ref TcPacketsBufferGetEffectiveLength
	(reception mode) and the maximum length with \ref TcPacketsBufferGetLength.
	\note In the current version of the TurboCap API, it's not possible to access the raw buffer of a packets
		buffer received from an aggregating instance, i.e. when capturing from a BAP or TcAP port.
		A call to \ref TcPacketsBufferGetBuffer will return NULL, and \ref TcPacketsBufferGetLength and 
		\ref TcPacketsBufferGetEffectiveLength will return 0.
*/
typedef HANDLE TC_PACKETS_BUFFER;
typedef TC_PACKETS_BUFFER *PTC_PACKETS_BUFFER;

/*!
	\brief Handle to a statistics object containing counters related to a port or an instance.

	The underlying packet capture and transmission engine maintains a set of counters, like the number
	of received or transmitted packets. Two sets of counters are available. 
	- Port statistics contain counters related to a physical port. Such counters are reset when
	the port is activated, i.e. at boot time or if the port (or the board containing it) is disabled
	and re-enabled. 
	- Instance statistics contain counters related to a capture and transmission instance. Such counters
	are reset to zero when the instance is created with \ref TcInstanceOpenByName or \ref TcInstanceOpenByPort.
	You obtain a statistics object by querying the given port or instance with \ref TcInstanceQueryStatistics or
	\ref TcPortQueryStatistics. 
	After a statistics handle is obtained, it's possible to query for the statistics of the object by calling 
	\ref TcStatisticsQueryValue. 
	The counters stored in a statistics object are not updated automatically (i.e. querying for a specific value
	with \ref TcStatisticsQueryValue doesn't update its value). You need to call TcStatisticsUpdate to update the
	counters.
*/
typedef HANDLE TC_STATISTICS;
typedef TC_STATISTICS *PTC_STATISTICS;

#endif //DO_NOT_DEFINE_TC_HANDLES

/*!
	\brief A list of the port types supported by the TurboCap library.
*/
typedef enum _TC_PORT_TYPE
{
	/*!
		\brief The port type is unknown.
	*/
	TC_PORT_TYPE_UNKNOWN = 0,
	/*!
		\brief Physical port i.e. a port on a board.
	*/
	TC_PORT_TYPE_PHYSICAL = 1,
	/*!
		\brief A Board Aggregating Port (BAP) i.e. a virtual port 
		aggregating the traffic coming from all the ports of a board.
	*/
	TC_PORT_TYPE_BAP	= 2,
	/*!
		\brief A TurboCap Aggregating Port (TCAP) i.e. a virtual port 
		aggregating the traffic coming from all the physical ports of the system.
	*/
	TC_PORT_TYPE_TCAP	= 3,
}
	TC_PORT_TYPE;

/*!
	\brief A list of the board types supported by the TurboCap2 library.
*/
typedef enum _TC_BOARD_TYPE
{
	/*!
		\brief The board type is unknown.
	*/
	TC_BOARD_TYPE_UNKNOWN = 0,
	/*!
		\brief The board is a Dual Port Gigabit copper card with an Intel Chipset
	*/
	TC_BOARD_TYPE_9402PT = 1
}
	TC_BOARD_TYPE;

/*!
	\brief Duplex setting of a port when the link is up.
*/
typedef enum _TC_LINK_DUPLEX_TYPE
{
	/*!
		\brief The duplex setting is unknown.
	*/
	TC_UNKNOWN_DUPLEX = 0,
	/*!
		\brief The port is in full duplex mode.
	*/
	TC_FULL_DUPLEX = 1,
	/*!
		\brief The port is in half duplex mode.
	*/
	TC_HALF_DUPLEX = 2
}
	TC_LINK_DUPLEX_TYPE;

/*!
	\brief Link information on a physical port.
*/
typedef struct _TC_LINK_INFO
{
	/*!
		\brief Link speed, in Mbps
		\note This field is undefined if the link is down.
	 */
	ULONG					LinkSpeed;
	/*!
		\brief Link duplex setting.
		\note This field is undefined if the link is down.
	 */
	TC_LINK_DUPLEX_TYPE	DuplexType;
	/*!
		\brief Link status. 

		This field is set to TRUE if the link is up, FALSE otherwise.
	 */
	BOOLEAN					LinkUp;
}
	TC_LINK_INFO;
typedef TC_LINK_INFO *PTC_LINK_INFO;

/*!
	\brief Available link speeds that can be configured for the autonegotiation
		or to force the link speed when autonegotation is disabled. Used
		in conjunction with \ref TC_AUTONEG_PARAMETERS.
*/
typedef enum _TC_SPEED_CONFIGURATION
{
	TC_SPEED_CONF_10MB_FD	= 0x00000001,	///< The port uses/must advertise a link speed of 10Mbps full duplex.
	TC_SPEED_CONF_10MB_HD	= 0x00000002,	///< The port uses/must advertise a link speed of 10Mbps half duplex.
	TC_SPEED_CONF_100MB_FD	= 0x00000004,	///< The port uses/must advertise a link speed of 100Mbps full duplex.
	TC_SPEED_CONF_100MB_HD	= 0x00000008,	///< The port uses/must advertise a link speed of 100Mbps half duplex.
	TC_SPEED_CONF_1000MB_FD	= 0x00000010,	///< The port uses/must advertise a link speed of 1Gbps full duplex.

	TC_SPEED_CONF_ALL		=	0x0000001F,
}
	TC_SPEED_CONFIGURATION;

/*!
	\brief Structure used with \ref TcPortQueryAutonegotiationParameters and \ref TcPortSetAutonegotiationParameters.
	
	In case of a query request, it returns the current autonegotiation parameters.
	
	In case of a set request, it allows to enable/disable autonegotiation, to set the speed advertised during autonegotiation
	or to force a specific speed in case autonegotiation is disabled.
*/
typedef struct _TC_AUTONEG_PARAMETERS
{
	/*!
		In case of a query operation, if autonegotiation is enabled (field \ref Enabled is TRUE),
		it contains a bitmask of \ref TC_SPEED_CONFIGURATION values indicating the link speeds currently advertised
		during autonegotiation. If autonegotiation is off, this field contains the link speed that is forced on the link (one and
		only one of the bit values in the \ref TC_SPEED_CONFIGURATION enumeration.
		
		In case of a set operation, if autonegotiation should be enabled  (field \ref Enabled is TRUE), it should contain the 
		link speeds that should be advertised upon autonegotiation. If autonegotiation is disabled (field \ref Enabled is FALSE),
		it contains the link speed that should be forced, one and only one of the values in the \ref TC_SPEED_CONFIGURATION enumeration.
	*/
	TC_SPEED_CONFIGURATION Configuration;	
	/*!
		In case of a query operation, it returns the link speeds supported by the port, as a bitwise combination of the
		\ref TC_SPEED_CONFIGURATION bit values.
		
		In case of a set operation, this field should be set to the same value as \ref Configuration.
	*/
	TC_SPEED_CONFIGURATION Mask;
	/*!
		In case of a query operation, TRUE if autonegotiation is enabled.
		
		In case of a set operation, enables or disables autonegotiation.
	*/
	BOOLEAN				   Enabled;
}
	TC_AUTONEG_PARAMETERS,  *PTC_AUTONEG_PARAMETERS;

C_ASSERT(sizeof(TC_AUTONEG_PARAMETERS) == 12);

typedef ULONG TC_STATUS;

/** 
 *  @}
 */

/** @defgroup counters Statistical counters
 *  @{
 */

/*!
	\brief Total number of bytes received by a port. In case of an aggregated port, it represents the sum of the packets received on each physical port
		which is part of the aggregation. This counter accounts for errored frames, too.
*/
#define TC_COUNTER_PORT_TOTAL_RX_BYTES			((ULONG)0x00000001)

/*!
	\brief Total number of packets received by a port. In case of an aggregated port, it represents the sum of the packets received on each physical port
		which is part of the aggregation. This counter accounts for errored frames, too.
*/
#define TC_COUNTER_PORT_TOTAL_RX_PACKETS		((ULONG)0x00000002)

/*!
	\brief Total number of packets received by a port with no errors. In case of an aggregated port, it represents the sum of the packets received on each physical port
		which is part of the aggregation.
*/
#define TC_COUNTER_PORT_RX_OK_PACKETS			((ULONG)0x00000003)

/*!
	\brief Total number of packets received by a port with errors. In case of an aggregated port, it represents the sum of the packets received on each physical port
		which is part of the aggregation.
*/
#define TC_COUNTER_PORT_RX_ERROR_PACKETS		((ULONG)0x00000004)

/*!
	\brief Total number of packets delivered to the physical port for transmission. This counter is incremented before the packets are actually
	transmitted by the underlying hardware. If the port link is down, this counter is incremented anyways, because the packets are stored in the port transmission buffer.
*/
#define TC_COUNTER_PORT_TOTAL_TX_PACKETS		((ULONG)0x00000005)

/*!
	\brief Total number of bytes delivered to the physical port for transmission. This counter is incremented before the packets are actually
	transmitted by the underlying hardware. If the port link is down, this counter is incremented anyways, because the packets are stored in the port transmission buffer.
	In case of an aggregated port, this counter is always 0.
*/
#define TC_COUNTER_PORT_TOTAL_TX_BYTES			((ULONG)0x00000006)

/*!
	\brief Total number of bytes received by an instance.
*/
#define TC_COUNTER_INSTANCE_TOTAL_RX_BYTES		((ULONG)0x00010001)

/*!
	\brief Total number of packets received by an instance.
*/
#define TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS	((ULONG)0x00010002)

/*!
	\brief Total number of bytes delivered to the physical port for transmission from this instance. This counter is incremented before the packets are actually
	transmitted by the underlying hardware. If the port link is down, this counter is incremented anyways, because the packets are stored in the port transmission buffer.
*/
#define TC_COUNTER_INSTANCE_TOTAL_TX_BYTES		((ULONG)0x00010003)

/*!
	\brief Total number of packets delivered to the physical port for transmission from this instance. This counter is incremented before the packets are actually
	transmitted by the underlying hardware. If the port link is down, this counter is incremented anyways, because the packets are stored in the port transmission buffer.
*/
#define TC_COUNTER_INSTANCE_TOTAL_TX_PACKETS	((ULONG)0x00010004)

/*!
	\brief Total number of packets received by an instance with no errors.
*/
#define TC_COUNTER_INSTANCE_RX_OK_PACKETS		((ULONG)0x00010005)

/*!
	\brief Total number of packets received by an instance with errors.
*/
#define TC_COUNTER_INSTANCE_RX_ERROR_PACKETS	((ULONG)0x00010006)

/*!
	\brief Total number of packets dropped by the hardware because the application is not fast enough at processing packets.
*/
#define TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS	((ULONG)0x00010007)

/** 
 *  @}
 */

//
// Internal note: all the error codes have bit 29 set to 1
// This follows the MS guidelines for the error codes returned
// by GetLastError(). System errors have this bit reset, 
// application defined errors have this bit set.
//

/** @defgroup error_codes Error codes
 *  @{
 */

/*!
	\brief The call was successful.
*/
#define	TC_SUCCESS					(TC_STATUS)0x00000000

/*!
	\brief The call was successful but a reboot is required
		for the operation to be effective.
*/
#define TC_SUCCESS_REBOOT_REQUIRED	(TC_STATUS)0x00000001

/*!
	\brief The port does not exist.
*/
#define TC_ERROR_NO_PORT			(TC_STATUS)0x20000001

/*!
	\brief An unknown error occurred.
*/
#define TC_ERROR_UNKNOWN			(TC_STATUS)0x20000002
	
/*!
	\brief This feature has not been implemented yet.
*/
#define TC_ERROR_NOT_IMPLEMENTED	(TC_STATUS)0x20000003

/*!
	\brief The request is invalid.
*/
#define	TC_ERROR_INVALID_REQUEST	(TC_STATUS)0x20000004

/*!
	\brief The requested counter in a statistics object is not available
*/
#define	TC_ERROR_NOT_AVAILABLE		(TC_STATUS)0x20000005

/*!
	\brief Not enough memory available on the system to complete the operation.
*/
#define TC_ERROR_NO_MEMORY			(TC_STATUS)0x20000006

/*!
	\brief The end of a packets buffer has been reached while reading packets from it.
*/
#define TC_ERROR_END_OF_BUFFER		(TC_STATUS)0x20000007

/*!
	\brief The data inside a packets buffer are inconsistent (e.g. the buffer is truncated or the values in the packet headers are not consistent).
*/
#define TC_ERROR_INCONSISTENT_BUFFER (TC_STATUS)0x20000008

/*!
	\brief The packets buffer is full and cannot hold the packet passed as parameter to the function.
*/
#define TC_ERROR_BUFFER_FULL		(TC_STATUS)0x20000009

/*!
	\brief The packet header has some invalid parameters.
*/
#define TC_INVALID_PACKET			(TC_STATUS)0x2000000A

/*!
	\brief A parameter passed to the function has an invalid value.
*/
#define TC_ERROR_INVALID_PARAMETER	(TC_STATUS)0x2000000B

/*!
	\brief Impossible to allocate an event used by the object.
*/
#define TC_ERROR_CANNOT_CREATE_EVENT (TC_STATUS)0x2000000C

/*!
	\brief I/O error while accessing a kernel device.
*/
#define TC_ERROR_IO_DEVICE_ERROR	(TC_STATUS)0x2000000D

/*!
	\brief The event handler has been already registered on the object.
*/
#define TC_ERROR_CALLBACK_ALREADY_REGISTERED (TC_STATUS)0x2000000E

/*!
	\brief The buffer passed to the function is too small to return
		the result of the operation.
*/
#define TC_ERROR_BUFFER_TOO_SMALL	(TC_STATUS)0x2000000F

/*!
	\brief The required information cannot be found in the registry.
*/
#define TC_ERROR_REG_PARAMETER_NOT_FOUND		(TC_STATUS)0x20000010


/** 
 *  @}
 */

/** @defgroup features Features
 *  @{
	
	This section enumerates the various feature values that can be set/queried on a board, a port or an instance with
	- \ref TcBoardSetFeature
	- \ref TcBoardQueryFeature
	- \ref TcPortSetFeature
	- \ref TcPortQueryFeature
	- \ref TcInstanceSetFeature
	- \ref TcInstanceQueryFeature
	
	Feature definition names follow a common scheme:

	TC_\<object\>_FT_\<name\>

	\<object\> is the type of object the feature applies to, namely
	- BRD for Board
	- PRT for Port
	- INST for Instance.

	\<name\> is the name of the feature itself.
	
 */
	
#define TC_PRT_LED_ON		((ULONG)0x00000000)
#define TC_PRT_LED_OFF		((ULONG)0x00000001)
#define TC_PRT_LED_BLINK	((ULONG)0x00000002)
#define TC_PRT_LED_DEFAULT	((ULONG)0x00000003)

/*!
	\brief It controls the status of the passthru feature of a board.

	<b>Supported operations</b>: Query/Set
	<br>
	<b>Scope</b>: board
	<br>
	<b>Possible values</b>:
		- 0: passthru is disabled
		- 1: passthru is enabled
*/
#define TC_BRD_FT_PASSTHRU		0x00000001	//R/W
/*!
	\brief It controls the status of LED #0 of a port.

	<b>Supported operations</b>: Query/Set
	<br>
	<b>Scope</b>: physical port
	<br>
	<b>Possible values</b>:
		\ref TC_PRT_LED_ON. The led is on.
		\ref TC_PRT_LED_OFF. The led is off. 
		\ref TC_PRT_LED_BLINK. The led is blinking.
		\ref TC_PRT_LED_DEFAULT. The led has the normal behavior. Led #0 is on when the link is up, 
			and blinking when data are sent/received on the port.
*/
#define TC_PRT_FT_LED_0		0x00000001	//R/W
/*!
	\brief It controls the status of LED #1 of a port.

	<b>Supported operations</b>: Query/Set
	<br>
	<b>Scope</b>: physical port
	<br>
	<b>Possible values</b>:
		\ref TC_PRT_LED_ON. The led is on (green).
		\ref TC_PRT_LED_OFF. The led is off. 
		\ref TC_PRT_LED_BLINK. The led is blinking (green).
		\ref TC_PRT_LED_DEFAULT. The led has the normal behavior. Led #1 is green when the negotiated speed is 100Mbps.
			Please note that on the \ref TC_BOARD_TYPE_9402PT board, Led #1 and Led #2 are combined. The color of the led 
			(green vs. orange) is controlled by both the settings of Led #1 and Led #2, and orange takes precedence over
			green.
*/
#define TC_PRT_FT_LED_1		0x00000002	//R/W

/*!
	\brief It controls the status of LED #2 of a port.

	<b>Supported operations</b>: Query/Set
	<br>
	<b>Scope</b>: physical port
	<br>
	<b>Possible values</b>:
		\ref TC_PRT_LED_ON. The led is on (orange).
		\ref TC_PRT_LED_OFF. The led is off. 
		\ref TC_PRT_LED_BLINK. The led is blinking (orange).
		\ref TC_PRT_LED_DEFAULT. The led has the normal behavior. Led #1 is green when the negotiated speed is 1000Mbps.
			Please note that on the \ref TC_BOARD_TYPE_9402PT board, Led #1 and Led #2 are combined. The color of the led 
			(green vs. orange) is controlled by both the settings of Led #1 and Led #2, and orange takes precedence over
			green.
*/
#define TC_PRT_FT_LED_2		0x00000003	//R/W


/*!
	\brief Internal feature.

	<b>Supported operations</b>: Query
	<br>
	<b>Scope</b>: physical port
	<br>
	<b>Possible values</b>:
*/
#define TC_PRT_FT_RX_SLOT_SIZE	0x00000004	//R
/*!
	\brief Internal feature.

	<b>Supported operations</b>: Query
	<br>
	<b>Scope</b>: physical port
	<br>
	<b>Possible values</b>:
*/
#define TC_PRT_FT_TX_SLOT_SIZE	0x00000005	//R
/*!
	\brief Internal feature.

	<b>Supported operations</b>: Query
	<br>
	<b>Scope</b>: physical port
	<br>
	<b>Possible values</b>:
*/
#define TC_PRT_FT_RX_SLOTS		0x00000006	//R
/*!
	\brief Internal feature.

	<b>Supported operations</b>: Query
	<br>
	<b>Scope</b>: physical port
	<br>
	<b>Possible values</b>:
*/
#define TC_PRT_FT_TX_SLOTS		0x00000007	//R
/*!
	\brief Internal feature.

	<b>Supported operations</b>: Query
	<br>
	<b>Scope</b>: physical port
	<br>
	<b>Possible values</b>:
*/
#define TC_PRT_FT_RX_DESCS		0x00000008	//R
/*!
	\brief Internal feature.

	<b>Supported operations</b>: Query
	<br>
	<b>Scope</b>: physical port
	<br>
	<b>Possible values</b>:
*/
#define TC_PRT_FT_TX_DESCS		0x00000009	//R

/*!
	\brief It controls the snapshot feature of a reception/transmission instance.

	When snapshotting is enabled, the capture engine returns at most the first snaplen 
	bytes of a packet. This feature is used to improve capture performance by bringing only
	the packet headers to user level and discarding the upper layer payloads.
	The snapshot feature affects the value of the \ref TC_PACKET_HEADER::CapturedLength field
	during reception: the value of this field is never greater than the snapshot length set with
	this feature parameter.

	<b>Supported operations</b>: Query/Set
	<br>
	<b>Scope</b>: instance
	<br>
	<b>Possible values</b>: 0-0xFFFF (65535)
		When snapshot is set to 0xFFFF, the whole packet is always captured (i.e. snapshotting is
		disabled). When snapshot is set to 0, then the capture engine returns the packet header structure
		(\ref TC_PACKET_HEADER) only.

*/
#define TC_INST_FT_SNAPLEN		0x00000001	//R/W

/*!
	\brief It controls the hardware filter for the received packets.

	The capture has the ability to capture or discard packets with correct FCS, or errored frames.

	<b>Supported operations</b>: Query/Set
	<br>
	<b>Scope</b>: instance
	<br>
	<b>Possible values</b>: An OR combination of the following values
		- \ref TC_HW_FILTER_CORRECT	Packets with no errors
		- \ref TC_HW_FILTER_WRONG_FCS  Packets with wrong FCS
		- \ref TC_HW_FILTER_PHY_ERROR  The PHY detected a physical error while receiving the packet.
	<b>Default value</b>: TC_HW_FILTER_CORRECT | TC_HW_FILTER_WRONG_FCS
*/
#define TC_INST_FT_HW_FILTER	0x00000002	//R/W

/*!
	\brief It controls the mintocopy feature of a port, i.e. the minimum amount of bytes that should
	be stored in the kernel buffer before the reception wait handle gets signalled (please see \ref 
	TcInstanceGetReceiveWaitHandle).

	<b>Supported operations</b>: Query/Set
	<br>
	<b>Scope</b>: instance
	<br>
	<b>Possible values</b>: 0 - 0xFFFFFFFF
		If mintocopy is set to 0, the reception wait handle is never signalled.
		\todo does this make sense? or it should be 0xFFFFFFF = no signal?
	<b>Default value</b>: 0xFFFF
*/
#define TC_INST_FT_MINTOCOPY	0x00000003	//R/W

/*!
	\brief It controls the reception functionality of an instance i.e. if reception is enabled or not.
		
	<b>Supported operations</b>: Query/Set
	<br>
	<b>Scope</b>: instance
	<br>
	<b>Possible values</b>: 
		- 0: reception is disabled
		- 1: reception is enabled

	\note
	- By default reception is disabled on a newly created instance.
	- Once enabled, reception cannot be disabled on a given instance.
*/
#define TC_INST_FT_RX_STATUS	0x00000004	//R/W

/*!
	\brief It controls the transmission functionality of an instance i.e. if transmission is enabled or not.
		
	<b>Supported operations</b>: Query/Set
	<br>
	<b>Scope</b>: instance
	<br>
	<b>Possible values</b>: 
		- 0: transmission is disabled
		- 1: transmission is enabled

	\note
	- By default transmission is disabled on a newly created instance.
	- Once enabled, transmission cannot be disabled on a given instance.
*/
#define TC_INST_FT_TX_STATUS	0x00000005	//R/W

/*!
	\brief It controls the read timeout of an instance, the maximum timeout after which a packet receive operation 
	will return.
		
	<b>Supported operations</b>: Query/Set
	<br>
	<b>Scope</b>: instance
	<br>
	<b>Possible values</b>: 1-9999 ms

	\note
	Under a LINUX operating system, the biggest possible value for aggregating instances is 3 ms. If the user attempts to set a higher value
	the read timeout will default to 3 ms. For physical instances the possible values are 1-9999 ms as under a WINDOWS operating system.
*/
#define TC_INST_FT_READ_TIMEOUT	0x00000006	//R/W

/*!
	\brief Used with the feature \ref TC_INST_FT_HW_FILTER. 
	When this bit flag is set, correct packets (i.e. valid FCS and no PHY errors) are captured.
*/
#define TC_HW_FILTER_CORRECT	0x00000001	

/*!
	\brief Used with the feature \ref TC_INST_FT_HW_FILTER. 
	When this bit flag is set, packets with a wrong FCS are captured.
*/
#define TC_HW_FILTER_WRONG_FCS	0x00000002

/*!
	\brief Used with the feature \ref TC_INST_FT_HW_FILTER. 
	When this bit flag is set, packets received with PHY errors are captured.
*/
#define TC_HW_FILTER_PHY_ERROR	0x00000004

/** 
 *  @}
 */

#ifdef __cplusplus
extern "C"
{
#endif

/** @defgroup global_functions Global functions
 *  @{
 */

/*!
	\brief It returns a list on all the available ports
	on the system, both physical and aggregating (TcAP and BAP).

	\param ppPorts Address of a caller allocated pointer to a TC_PORT. 
		On success, the pointer will point to an array of port handles 
		available on the system.
		The returned list must be freed with \ref TcFreePortList.
	\param pLength Address of a caller allocated unsigned long. 
		On success, it contains the number of entries in the array of
		port handles ppPorts.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS
TC_CALLCONV 
TcQueryPortList(
						  __out__ PTC_PORT *ppPorts, 
						  __out__ PULONG pLength
						  );

/*!
	\brief It frees a list of port handles returned by \ref TcQueryPortList .

	\param pPorts A list of port handles previously returned by \ref TcQueryPortList .
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS 
TC_CALLCONV
TcFreePortList(
						   __in__ PTC_PORT pPorts
						   );
/*!
	\brief It translates a status code returned by one of the functions into an error string.

	\param status A status code (in the \ref error_codes section) returned by one of 
	functions in the library.

	\return A constant string describing the error. The returned string must not be released 
		or modified.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
PCHAR 
TC_CALLCONV 
TcStatusGetString(
							__in__ TC_STATUS status
						);
						 
/** 
 *  @}
 */

/** @defgroup port_functions Port related functions
 *  @{
 */

/*!
	\brief It returns the name of a given port.

	\param port The handle of a port to query for the name
	\return Pointer to a string containing the port name.
	\note
		- the returned name string must not be freed.
		- the returned name is unique on a machine.
		- the returned string should not be modified.
		- the name can be used in a subsequent call to \ref TcInstanceOpenByName.
		- the returned string until the given port handle is valid. If the port handle comes from
		a list returned by \ref TcQueryPortList, the name is valid until the list is destroyed. 
		If the handle comes (directly or indirectly) from an instance (\ref TC_INSTANCE), then
		the name is valid until the instance is closed.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
PCHAR
TC_CALLCONV 
TcPortGetName(
						  __in__ TC_PORT port
						 );

/*!
	\brief It returns the board handle containing the given port.

	\param port The handle of a port to query for the board
	\param pBoard Pointer to a board handle. On success it will contain the handle to the board.
	\note
		- the returned handle must not be freed.
		- the returned handle until the given port handle is valid. If the port handle comes from
		a list returned by \ref TcQueryPortList, the board is valid until the list is destroyed. 
		If the port handle comes (directly or indirectly) from an instance (\ref TC_INSTANCE), then
		the board handle is valid until the instance is closed.

	\return \ref TC_SUCCESS in case of a physical or BAP port, \ref TC_ERROR_INVALID_REQUEST in case of a 
		TcAP port.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS 
TC_CALLCONV 
TcPortQueryBoard(
						__in__ TC_PORT port,
						__out__ PTC_BOARD pBoard
						 );

/*!
	\brief It returns the description of a given port.

	\param port The handle of a port to get the description from.
	\return Pointer to a string containing the port description.
	\note
		- the description string must not be freed.
		- the description is not unique on a machine i.e. multiple ports with different names can have the same 
		  description.
		- the returned string should not be modified.
		- the returned string until the given port handle is valid. If the port handle comes from
		a list returned by \ref TcQueryPortList, the string is valid until the list is destroyed. 
		If the handle comes (directly or indirectly) from an instance (\ref TC_INSTANCE), then
		the string is valid until the instance is closed.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
PCHAR
TC_CALLCONV 
TcPortGetDescription(
							__in__ TC_PORT port
					);

/*!
	\brief It sets the description of a given physical port.

	\param port The handle of a port to set the description of.
	\param pPortName Pointer to a string containing the port description.

	\return One of the \ref error_codes values.

	\note
		- the description string gets copied internally, and can be freed upon this function returns.
		- it's not possible to change the description of aggregating (BAP and T2AP) ports.

	<b>Thread safety</b>: this function is thread safe if called on different ports. Calling this function on the same port from multiple threads concurrently can lead to unexpected results.
*/
TC_STATUS
TC_CALLCONV
TcPortSetDescription(
							__in__ TC_PORT port,
							__in__ PCHAR pPortName
					);

/*!
	\brief It returns the type of a given port.

	\param port The handle of a port to query for the type.

	\return One of the values in \ref TC_PORT_TYPE

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_PORT_TYPE
TC_CALLCONV
TcPortGetType(
					 __in__ TC_PORT port
					 );

/*!
	\brief It queries a port for the MAC address.

	\param port The handle of a port to query for the MAC address
	\param pMac A caller allocated array of at least 6 bytes to hold the MAC address of the port.

	\return One of the \ref error_codes values.

	\note It's possible to query the MAC address of physical ports, only. Querying the MAC address
		of a BAP or TcAP port will result in a \ref TC_ERROR_INVALID_REQUEST error.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS 
TC_CALLCONV 
TcPortQueryMacAddress(
							__in__ TC_PORT port,
							__out__ BYTE pMac[6]
						);

/*!
	\brief It queries an aggregating port for the list of physical ports that it aggregates.

	\param aggregatingPort The handle of a port to query.
	\param ppPorts Address of a caller allocated pointer to a TC_PORT. 
		On success, the pointer will point to an array of port handles aggregated by the port.
		The returned list must not be freed.
	\param pLength Address of a caller allocated unsigned long. 
		On success, it contains the number of entries in the array of
		port handles ppPorts.

	\return One of the \ref error_codes values.

	\note
	- It's possible to query aggregating ports (BAP and TcAP), only. Querying physical ports
		will result in a \ref TC_ERROR_INVALID_REQUEST error.
	- The returned list must not be freed.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS 
TC_CALLCONV 
TcPortQueryAggregatedPortList(
						    __in__ TC_PORT aggregatingPort,
							__out__ PTC_PORT *ppPorts,
							__out__ PULONG pLength
							);

/*!
	\brief It compares two port handles to check if they correspond to the same port.

	\param portA Handle to the first port
	\param portB Handle to the second port

	\return TRUE if the two port handles correspond to the same port (being it physical or
		aggregating).

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
BOOLEAN
TC_CALLCONV
TcPortIsEqual(
					   __in__ TC_PORT portA,
					   __in__ TC_PORT portB
					   );

/*!
	\brief Queries a port for the link status.

	\param port Handle to the port to query.
	\param pLinkInfo Pointer to a caller allocated TC_LINK_INFO structure. On success it
		contains the status of the link of the port.

	\return One of the \ref error_codes values.

	\note It's possible to query the link status of physical ports, only. Querying a BAP 
	or TcAP port will result in a \ref TC_ERROR_INVALID_REQUEST error. 

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS 
TC_CALLCONV 
TcPortQueryLinkStatus(
										__in__ TC_PORT port,
										__out__ PTC_LINK_INFO pLinkInfo
									);

/*!
	\brief It queries the statistics of a physical port.
	
	\param port Port handle
	\param pStatistics Pointer to a caller allocated statistics handle. On success it will return a valid statistics handle.
		In case of success, the returned statistics handle should be released with \ref TcStatisticsDestroy.
	\return One of the \ref error_codes values.

	\note It's not possible to query the statistics of a virtual port.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS
TC_CALLCONV
TcPortQueryStatistics(
										__in__ TC_PORT port,
										__out__ PTC_STATISTICS pStatistics
										);

/*!
	\brief It sets a specific feature on the port.
	
	\param port Port handle
	\param feature Identifier of the feature. A list of the available features can be found in section \ref features.
	\param value Value of the feature to be set. Please refer to the documentation of the specific feature you are trying to set in section \ref features. 
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS
TC_CALLCONV
TcPortSetFeature(
						__in__ TC_PORT port,
						__in__ ULONG feature,
						__in__ ULONG value
					);

/*!
	\brief It queries a specific feature on the port.
	
	\param port Port handle
	\param feature Identifier of the feature. A list of the available features can be found in section \ref features.
	\param pValue Pointer to a 32bit integer. On success it will return the value of the feature. 
		Please refer to the documentation in section \ref features to know what values can be returned by querying a specific feature.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS
TC_CALLCONV
TcPortQueryFeature(
						__in__ TC_PORT port,
						__in__ ULONG feature,
						__out__ PULONG pValue
					);

/*!
	\brief It sets the autonegotiation parameters of a physical port i.e. it enables/disables autonegotiation
		and controls which link speeds should be advertised during autonegotiation.

	\param port Handle to a physical port.
	\param autonegParameters Parameters to enable/disable autonegotiation, set the advertised link speeds
		or force a link speed. Please refer to the documentation of \ref TC_AUTONEG_PARAMETERS for details
		on autonegotiation.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe if called on different port handles (\ref TC_PORT). 
		Calling this function on the same port from concurrent threads yields undefined results.

	\note It's possible to set the autonegotiation parameters of physical ports, only. Calling this function on
	a BAP or TcAP port will result in a \ref TC_ERROR_INVALID_REQUEST error.
		
*/
TC_STATUS
TC_CALLCONV
TcPortSetAutonegotiationParameters(
										__in__ TC_PORT port,
										__in__ TC_AUTONEG_PARAMETERS autonegParameters
										);


/*!
	\brief It queries the autonegotiation parameters of a port i.e. if autonegotiation is enabled, which 
	link speed be advertised during autonegotiation and which link speeds are supported by the port.

	\param port Handle to a physical port.
	\param pAutonegParameters Address of a caller allocated \ref TC_AUTONEG_PARAMETERS structure.
		On success it contain the current autonegotiation parameters. Please refer to the documentation 
		of \ref TC_AUTONEG_PARAMETERS for details on autonegotiation.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe if called on different port handles (\ref TC_PORT). 
		Calling this function on the same port from concurrent threads yields undefined results.

	\note It's possible to query the autonegotiation parameters of physical ports, only. Calling this function on
	a BAP or TcAP port will result in a \ref TC_ERROR_INVALID_REQUEST error.
		
*/
TC_STATUS
TC_CALLCONV
TcPortQueryAutonegotiationParameters(
										__in__ TC_PORT port,
										__out__ PTC_AUTONEG_PARAMETERS pAutonegParameters
										);

/** 
 *  @}
 */

/** @defgroup board_functions Board related functions
 *  @{
 */

/*!
	\brief It queries a board for the list of physical ports that it contains.

	\param board The handle of a board to query.
	\param ppPorts Address of a caller allocated pointer to a TC_PORT. 
		On success, the pointer will point to an array of port handles in the board.
		The returned list must not be freed.
	\param pLength Address of a caller allocated unsigned long. 
		On success, it contains the number of entries in the array of
		port handles ppPorts.

	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS 
TC_CALLCONV 
TcBoardQueryPortList(
							__in__ TC_BOARD board,
							__in__ PTC_PORT *ppPorts,
							__out__ PULONG pLength
							);

/*!
	\brief It returns the type of a given board.

	\param board The handle of a board to query for the type.

	\return One of the values in \ref TC_BOARD_TYPE

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_BOARD_TYPE
TC_CALLCONV
TcBoardGetType(
				   __in__ TC_BOARD board
				   );

/*!
	\brief It returns the description of a given board.

	\param board The handle of a board to get the description from.
	\return A string containing the description of the board.
	\note
		- the description string must not be freed.
		- the description is not unique on a machine i.e. multiple boards can have the same 
		  description.
		- the returned string should not be modified.
		- the returned string until the given board handle is valid. 

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
PCHAR
TC_CALLCONV 
TcBoardGetDescription(
							__in__ TC_BOARD board
						);

/*!
	\brief It compares two board handles to check if they correspond to the same board.

	\param boardA Handle to the first board
	\param boardB Handle to the second board

	\return TRUE if the two board handles correspond to the same board.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
BOOLEAN
TC_CALLCONV
TcBoardIsEqual(
					   __in__ TC_BOARD boardA,
					   __in__ TC_BOARD boardB
					   );

/*!
	\brief It sets a specific feature on the board.
	
	\param board Board handle
	\param feature Identifier of the feature. A list of the available features can be found in section \ref features.
	\param value Value of the feature to be set. Please refer to the documentation of the specific feature you are trying to set in section \ref features. 
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS
TC_CALLCONV
TcBoardSetFeature(
						__in__ TC_BOARD board,
						__in__ ULONG feature,
						__in__ ULONG value
					);

/*!
	\brief It queries a specific feature on the board.
	
	\param board Board handle
	\param feature Identifier of the feature. A list of the available features can be found in section \ref features.
	\param pValue Pointer to a 32bit integer. On success it will return the value of the feature. 
		Please refer to the documentation in section \ref features to know what values can be returned by querying a specific feature.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS
TC_CALLCONV
TcBoardQueryFeature(
						__in__ TC_BOARD board,
						__in__ ULONG feature,
						__out__ PULONG pValue
					);


/** 
 *  @}
 */

/** @defgroup instance_functions Instance related functions
 *  @{
 */

/*!
	\brief It opens a reception/transmission instance of a port given a port handle.

	\param port port that the open instance handle will correspond to to.
	\param pInstance pointer to a caller allocated instance handle. On success it
		will contain an handle to the opened instance.
	\return One of the \ref error_codes values.

	\note The opened instance must be closed with \ref TcInstanceClose.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS 
TC_CALLCONV 
TcInstanceOpenByPort(
							__in__ TC_PORT port,
							__out__ PTC_INSTANCE pInstance
						);

/*!
	\brief It opens a reception/transmission instance of a port given the port unique name.

	\param name Unique name of the port to open, as returned by \ref TcPortGetName.
	\param pInstance pointer to a caller allocated instance handle. On success it
		will contain an handle to the opened instance.
	\return One of the \ref error_codes values.

	\note The opened instance must be closed with \ref TcInstanceClose.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS 
TC_CALLCONV 
TcInstanceOpenByName(
							__in__ PCHAR name,
							__out__ PTC_INSTANCE pInstance
						);

/*!
	\brief It closes an reception/transmission instance.

	\param instance Handle to the instance to close.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe if called on different instance handles (\ref TC_INSTANCE). 
		Calling this function on the same instance from concurrent threads must be synchronized.
*/
TC_STATUS 
TC_CALLCONV 
TcInstanceClose(
							__in__ TC_INSTANCE instance
						);

/*!
	\brief It returns the underlying port handle of an instance.
	
	\param instance Instance handle
	\return handle to the port.

	<b>Thread safety</b>: this function is thread safe if called on different instance handles (\ref TC_INSTANCE). 
		Calling this function on the same instance from concurrent threads must be synchronized.
*/
TC_PORT
TC_CALLCONV
TcInstanceGetPort(
							 __in__ TC_INSTANCE instance
							 );
/*!
	\brief This event callback function processes a link status change event.

	\param	instance Instance handle on which the event callback function was registered.
	\param linkInfo The new status of the link.
	\param context Context parameter registered when calling \ref TcInstanceRegisterEvtLinkStatusChange.
*/
typedef VOID (TC_CALLCONV *TcInstanceEvtLinkStatusChange)(
									  __in__ TC_INSTANCE instance,
									  __in__ TC_LINK_INFO linkInfo,
									  __in__ PVOID context
									  );

/*!
	\brief It registers an event handler that gets called whenever the link status changes.
	
	\param instance Instance handle
	\param eventHandler Pointer to a function that will be invoked when the link status of
		the port changes.
	\param context A context parameter that gets passed unmodified to the eventHandler when
		the handler gets invoked.
	\return One of the \ref error_codes values.
	\note
	- It's not possible to register more than one event handler per instance handle
	- I'ts not possible to deregister the event handler. The event handler is registered until
		the instance handle gets closed.
	- The eventHandler gets invoked on an arbitrary thread.
	- It's not possible to register an eventHandler on an aggregating port.

	<b>Thread safety</b>: this function is thread safe if called on different instance handles (\ref TC_INSTANCE). 
		Calling this function on the same instance from concurrent threads must be synchronized.
*/
TC_STATUS 
TC_CALLCONV 
TcInstanceRegisterEvtLinkStatusChange
									(
										__in__ TC_INSTANCE instance,
										__in__ TcInstanceEvtLinkStatusChange eventHandler,
										__in__ PVOID context
									);


/*!
	\brief It sets a specific feature on the instance.
	
	\param instance Instance handle
	\param feature Identifier of the feature. A list of the available features can be found in section \ref features.
	\param value Value of the feature to be set. Please refer to the documentation of the specific feature you are trying to set in section \ref features. 
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe if called on different instance handles (\ref TC_INSTANCE). 
		Calling this function on the same instance from concurrent threads must be synchronized.
*/
TC_STATUS 
TC_CALLCONV 
TcInstanceSetFeature(
								__in__ TC_INSTANCE instance,
								__in__ ULONG feature,
								__in__ ULONG value
							 );

/*!
	\brief It queries a specific feature on the instance.
	
	\param instance Instance handle
	\param feature Identifier of the feature. A list of the available features can be found in section \ref features.
	\param pValue Pointer to a 32bit integer. On success it will return the value of the feature. 
		Please refer to the documentation in section \ref features to know what values can be returned by querying a specific feature.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe if called on different instance handles (\ref TC_INSTANCE). 
		Calling this function on the same instance from concurrent threads must be synchronized.
*/
TC_STATUS 
TC_CALLCONV 
TcInstanceQueryFeature(
								__in__ TC_INSTANCE instance,
								__in__ ULONG feature,
								__out__ PULONG pValue
							);
/*!
	\brief It receives packets from a specific port.
	
	\param instance Instance handle
	\param pBuffer Pointer to a caller allocated packets buffer handle. On success, if some packets were received,
		it will contain a valid packets buffer instance. Otherwise it will be set to NULL. On failure, the pointer is
		not touched.
	\return One of the \ref error_codes values.

	\note 
	- This API is non-blocking i.e. it returns immediately, even if no packets are available.
	- The returned packets buffer should be released with \ref TcPacketsBufferDestroy.
	- When a valid packets buffer is returned in the pBuffer parameter, the caller owns the packets buffer
		until it calls \ref TcPacketsBufferDestroy.
	- For performance reasons, the library maintains an internal pool of packets buffers that are
		returned by this function. It's strongly suggested to release the packets buffers to the library
		with \ref TcPacketsBufferDestroy as soon the the application is done with the packets contained in
		the buffer.

	<b>Thread safety</b>: this function is thread safe. It's possible to call this function on the same instance from concurrent threads at the same time.
		Moreover, the returned packets buffers returned by this function can be destroyed (with \ref TcPacketsBufferDestroy) on an arbitrary thread without
		the need of any synchronization, with the condition that the instance must not be destroyed in the meantime.
		Also, it's safe to call this function and \ref TcInstanceQueryStatistics from different threads concurrently.

*/
TC_STATUS
TC_CALLCONV
TcInstanceReceivePackets(
							__in__ TC_INSTANCE instance,
							__out__ PTC_PACKETS_BUFFER pBuffer
							);

/*!
	\brief It returns a Windows waitable handle that gets signalled when some packets are available to be received.
	
	\param instance Instance handle
	\return A Win32 handle to wait on with the standard Win32 wait calls like WaitForSingleObject and WaitForMultipleObjects(Ex).

	\note The event gets signalled when at least "mintocopy" bytes are available in the kernel buffer to be brought to user level with
		\ref TcInstanceReceivePackets.

	<b>Thread safety</b>: this function is thread safe if called on different instance handles (\ref TC_INSTANCE). 
		Calling this function on the same instance from concurrent threads must be synchronized.
*/
HANDLE
TC_CALLCONV
TcInstanceGetReceiveWaitHandle(
						   __in__ TC_INSTANCE instance
						   );

/*!
	\brief It transmits a packets buffer on the port described by a given instance.

	\param instance Instance handle to the port that has to be used to transmit packets.
	\param buffer Handle to the packets buffer that has to be transmitted. 

	\return One of the \ref error_codes values.

	\note
		- This function is blocking i.e. it will not return until all the packets have been passed to the transmission engine or an error occurs.
		- When the function returns, the caller is again the owner of the packets buffer and can release it.
		- When this function successfully returns, it means that the packets have all been moved to the tranmission engine, and the board is still
			transmitting the packets.
	
	<b>Thread safety</b>: this function is thread safe if called on different instance handles (\ref TC_INSTANCE). 
		Calling this function on the same instance from concurrent threads must be synchronized. 
*/
TC_STATUS
TC_CALLCONV
TcInstanceTransmitPackets(
							__in__ TC_INSTANCE instance,
							__in__ TC_PACKETS_BUFFER buffer
						);

/*!
	\brief It queries the statistics of an instance.
	
	\param instance Instance handle
	\param pStatistics Pointer to a caller allocated statistics handle. On success it will return a valid statistics handle.
		In case of success, the returned statistics handle should be released with \ref TcStatisticsDestroy.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe if called on different instance handles (\ref TC_INSTANCE). 
		Calling this function on the same instance from concurrent threads must be synchronized. Also, it's safe
		to call this function and \ref TcInstanceReceivePackets from different threads concurrently.
*/
TC_STATUS
TC_CALLCONV
TcInstanceQueryStatistics(
										__in__ TC_INSTANCE instance,
										__out__ PTC_STATISTICS pStatistics
										);

/** 
 *  @}
 */

/** @defgroup packets_buffer_functions Packets buffer related functions
 *  @{
 */

/*!
	\brief It returns the underlying raw buffer of a packets buffer.
	
	\param buffer Handle to the packets buffer.
	\return A pointer to the underlying raw buffer. Use \ref TcPacketsBufferGetLength
		to obtain the length of such buffer.
	\note In the current version of the TurboCap API, it's not possible to access the raw buffer of a packets
		buffer received from an aggregating instance, i.e. when capturing from a BAP or TcAP port.
		In this case the return value is a NULL pointer.


	<b>Thread safety</b>: this function is thread safe if called on different packets buffer handles (\ref TC_PACKETS_BUFFER). 
		Calling this function on the same packets buffer from concurrent threads must be synchronized.
*/
PVOID
TC_CALLCONV
TcPacketsBufferGetBuffer(
							__in__ TC_PACKETS_BUFFER buffer
						);

/*!
	\brief It returns the effective length of a packets buffer i.e. the number of bytes that have been
		effectively used for packets in the internal raw buffer.

	During reception, the effective length is the number of bytes in the internal raw buffer that actually
	contain packets. The total length of the buffer (as obtained by \ref TcPacketsBufferGetLength) is always
	greater or equal to the effective length.

	During transmission, the effective length is the number of bytes in the internal raw buffer that need to
	be transmitted. The total length of the buffer (as obtained by \ref TcPacketsBufferGetLength) is always
	greater or equal to the effective length.
	
	\param buffer Handle to the packets buffer.
	\return The effective length of the underlying raw buffer. Use \ref TcPacketsBufferGetLength
		to obtain the total length of such buffer.
	\note In the current version of the TurboCap API, it's not possible to access the raw buffer of a packets
		buffer received from an aggregating instance, i.e. when capturing from a BAP or TcAP port.
		In this case the return value is 0.

	<b>Thread safety</b>: this function is thread safe if called on different packets buffer handles (\ref TC_PACKETS_BUFFER). 
		Calling this function on the same packets buffer from concurrent threads must be synchronized.
*/
ULONG
TC_CALLCONV
TcPacketsBufferGetEffectiveLength(
							__in__ TC_PACKETS_BUFFER buffer
						);

/*!
	\brief It returns the total length of a packets buffer i.e. the size of the internal raw buffer.

	\param buffer Handle to the packets buffer.
	\return The total length of the underlying raw buffer. Use \ref TcPacketsBufferGetEffectiveLength
		to obtain the effective length of such buffer i.e. the number of bytes that are actually in use.
	\note In the current version of the TurboCap API, it's not possible to access the raw buffer of a packets
		buffer received from an aggregating instance, i.e. when capturing from a BAP or TcAP port.
		In this case the return value is 0.

	<b>Thread safety</b>: this function is thread safe if called on different packets buffer handles (\ref TC_PACKETS_BUFFER). 
		Calling this function on the same packets buffer from concurrent threads must be synchronized.
*/
ULONG
TC_CALLCONV
TcPacketsBufferGetLength(
							__in__ TC_PACKETS_BUFFER buffer
						);

/*!
	\brief It creates a packets buffer used for transmission given its internal raw buffer size.

	\param size Size of the internal raw buffer, in bytes.
	\param pBuffer Pointer to a caller allocated packets buffer handle. On success it will contain a
		valid packets buffer handle.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe i.e. it can be called from multiple threads concurrently.
*/
TC_STATUS
TC_CALLCONV
TcPacketsBufferCreate(
							__in__ ULONG size,
							__out__ PTC_PACKETS_BUFFER pBuffer
						);

/*!
	\brief It releases a buffer previously allocated by \ref TcPacketsBufferCreate or returned by
		\ref TcInstanceReceivePackets.

	\param buffer Handle to the packets buffer to destroy.

	<b>Thread safety</b>: this function is thread safe if called on different packets buffer handles (\ref TC_PACKETS_BUFFER). 
		Calling this function on the same packets buffer from concurrent threads must be synchronized.
		<br>Also, please see the Thread Safety note in \ref TcInstanceReceivePackets regarding how to destroy the packets buffers
		returned by that function.
*/
VOID
TC_CALLCONV
TcPacketsBufferDestroy(
							__in__ TC_PACKETS_BUFFER buffer
						);

/*!
	\brief It resets the internal index used to read packets with \ref TcPacketsBufferQueryNextPacket to the beginning of the buffer.

	Each packets buffer maintains an internal index used to read packets with \ref TcPacketsBufferQueryNextPacket.
	This counter is automatically reset to the first packet in a packets buffer when a packets buffer is created or when the packets buffer is
	returned by \ref TcInstanceReceivePackets. This function should be used when the packets within a packets buffer should be scanned multiple times, 
	as in the code snippet below

	\code
	while(TcPacketsBufferQueryNextPacket(packetsBuffer, &header, &data) == TC_SUCCESS)
	{
		//
		// process packet
		//
	}
	
	//
	// reset the index
	//
	TcPacketsBufferResetIndex(packetsBuffer);

	//
	// scan the packets again
	//
	while(TcPacketsBufferQueryNextPacket(packetsBuffer, &header, &data) == TC_SUCCESS)
	{
		//
		// process packet 2nd time
		//
	}
	\endcode

	\param buffer Handle to the packets buffer.

	\note In the current version of the TurboCap API, it's not possible to reset the buffer index of a packets
		buffer received from an aggregating instance, i.e. when capturing from a BAP or TcAP port.

	<b>Thread safety</b>: this function is thread safe if called on different packets buffer handles (\ref TC_PACKETS_BUFFER). 
		Calling this function on the same packets buffer from concurrent threads must be synchronized.
*/
VOID
TC_CALLCONV
TcPacketsBufferResetIndex(
							__in__ TC_PACKETS_BUFFER buffer
						);

/*!
	\brief It returns the next available packet within a packets buffer.

	Each packets buffer maintains an internal index used to read packets.
	This function returns the next available packet (i.e. the one pointed to by the internal read index) and updates the internal read index.
	If the end of the packets buffer has been reached, the function returns \ref TC_ERROR_END_OF_BUFFER.

	\param buffer Handle to the packets buffer.
	\param pHeader Pointer to a caller allocated \ref TC_PACKET_HEADER. On success it will contain the header of the packet.
	\param ppData Pointer to a a caller allocated VOID pointer. On success, it will point to the packet, starting from the Ethernet header.
		The returned packet must not be freed. The packet remains valid until the packets buffer itself is valid.
	\return
	- \ref TC_SUCCESS if the packet was retrieved correctly
	- \ref TC_ERROR_END_OF_BUFFER is the end of the packets buffer was reached
	- \ref TC_ERROR_INCONSISTENT_BUFFER if an anomaly has been found in the buffer.

	<b>Thread safety</b>: this function is thread safe if called on different packets buffer handles (\ref TC_PACKETS_BUFFER). 
		Calling this function on the same packets buffer from concurrent threads must be synchronized.
*/
TC_STATUS
TC_CALLCONV
TcPacketsBufferQueryNextPacket(
							__in__ TC_PACKETS_BUFFER buffer,
							__out__ PTC_PACKET_HEADER pHeader,
							__out__ PVOID *ppData
							);


/*!
	\brief It adds a packet to a given packets buffer.

	The packet and the header passed as parameters are copied in the internal buffer used to hold the packets. The effective buffer length of the buffer
	(i.e. the number of bytes used in the internal buffer), as returned by \ref TcPacketsBufferGetEffectiveLength is updated on success. In case the 
	free bytes in the internal buffer (Length - EffectiveLength) are not enough to hold the packet, the function fails with error code \ref TC_ERROR_BUFFER_FULL.

	\param buffer Handle to the packets buffer.
	\param pHeader Pointer to the header describing the packet to be added to the packets buffer.
	\param pData Pointer to the buffer containing the packet itself, starting from the Ethernet header.
	\return 
	- \ref TC_SUCCESS in case of success.
	- \ref TC_ERROR_BUFFER_FULL if the free bytes in the internal buffer cannot hold the packet.
	- \ref TC_INVALID_PACKET if the header passed as parameter is not consistent. 

	\note  
		- The packet buffer passed as parameter (pData) can be freed after a call to this function. This function makes a internal copy of the packet data.
		- It's not possible to add packets to a packets buffer received from an aggregating port (BAP or TcAP port).

	<b>Thread safety</b>: this function is thread safe if called on different packets buffer handles (\ref TC_PACKETS_BUFFER). 
		Calling this function on the same packets buffer from concurrent threads must be synchronized.
*/
TC_STATUS
TC_CALLCONV
TcPacketsBufferCommitNextPacket(
							__in__ TC_PACKETS_BUFFER buffer,
							__in__ PTC_PACKET_HEADER pHeader,
							__in__ PVOID pData
							);

/*!
	\brief It sets the effective length of the buffer i.e. the number of bytes that actually contain packets in the internal
		raw buffer.
	\param buffer Handle to the packets buffer.
	\param effectiveLength Length of the bytes effectively in use in the internal buffer. This number must be less or equal to
		the maximum buffer size as returned by \ref TcPacketsBufferGetLength.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe if called on different packets buffer handles (\ref TC_PACKETS_BUFFER). 
		Calling this function on the same packets buffer from concurrent threads must be synchronized.
*/
TC_STATUS
TC_CALLCONV
TcPacketsBufferSetEffectiveLength(
						   __in__ TC_PACKETS_BUFFER buffer,
						   __in__ ULONG effectiveLength
						   );

/** 
 *  @}
 */

/** @defgroup statistics_functions Statistics related functions
 *  @{
 */

/*!
	\brief It releases a statistics handle returned by \ref TcPortQueryStatistics or \ref TcInstanceQueryStatistics.
		
	\param statistics Handle to the statistics handle to be destroyed.

	<b>Thread safety</b>: this function is thread safe if called on different statistics handles (\ref TC_STATISTICS). 
		Calling this function on the same statistics handle from concurrent threads must be synchronized.
*/
VOID
TC_CALLCONV
TcStatisticsDestroy(
					__in__ TC_STATISTICS statistics
					);

/*!
	\brief It updates the port or instance statistics referred to by a given handle.
		
	\param statistics Handle to the statistics to be updated.
	\return One of the \ref error_codes values.

	<b>Thread safety</b>: this function is thread safe if called on different statistics handles (\ref TC_STATISTICS). 
		Calling this function on the same statistics handle from concurrent threads must be synchronized.
*/
TC_STATUS
TC_CALLCONV
TcStatisticsUpdate(
					__in__ TC_STATISTICS statistics
					);

/*!
	\brief It queries a statitics object for a specific counter of an instance or a port.
		
	\param statistics Handle to the statistics object to query.
	\param counterId Identifier of the counter to be queried for in the statistics object.
		Possible values are listed in the section \ref counters.
	\param pValue Pointer to a caller allocated 64bit integer value. On success, it will return the
		queried counter.
	\return 
	- \ref TC_SUCCESS in case of success or
	- \ref TC_ERROR_NOT_AVAILABLE if the counter is not available for the instance or port.

	<b>Thread safety</b>: this function is thread safe if called on different statistics handles (\ref TC_STATISTICS). 
		Calling this function on the same statistics handle from concurrent threads must be synchronized.

*/
TC_STATUS
TC_CALLCONV
TcStatisticsQueryValue(
					__in__ TC_STATISTICS statistics,
					__in__ ULONG counterId,
					__out__ PULONGLONG pValue
					);

/** 
 *  @}
 */

#ifdef __cplusplus
}
#endif


#endif /*__TC_API_HEADER__*/
